package com.lili.collection.core.processor;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import org.apache.commons.lang3.StringUtils;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 *描述: json基于保存完整结构体的扁平化处理器
 *@date: 2023/10/28  15:46
 *@author: lili
 */
public class    JSONFullFormatFlatProcessor {

    public static Map<String, Object> jsonFlattenAsMap(String jsonData) {
        if(StringUtils.isBlank(jsonData)){
            return null;
        }
        return jsonFlattenAsMap(JSON.parse(jsonData));
    }

    public static Map<String, Object> jsonFlattenAsMap(Object jsonObj) {
        // 有序HashMap
        Map<String, Object> flatMap = new LinkedHashMap<>();
        reduce(flatMap, "", jsonObj);
        return flatMap;
    }

    private static void reduce(Map<String, Object> flatMap, String key, Object jsonObj) {
        // 如果是对象，对JSON对象进行解释
        if (jsonObj instanceof JSONObject) {
            JSONObject parseJsonObj = (JSONObject) jsonObj;
            if (parseJsonObj.isEmpty()) {
                // 如果是空对象，返回空对象
                flatMap.put(key, parseJsonObj);
            } else {
                for (Map.Entry<String, Object> entry : parseJsonObj.entrySet()) {
                    String entryKey = entry.getKey();
                    Object entryValue = entry.getValue();
                    String concatKey = StringUtils.isNotBlank(key)  ? key.concat(".").concat(entryKey) : entryKey;
                    if (entryValue instanceof JSONObject) {
                        reduce(flatMap, concatKey, entryValue);
                    } else if (entryValue instanceof JSONArray) {
                        reduce(flatMap, concatKey, entryValue);
                    } else {
                        // 放置所有连接值
                        flatMap.put(concatKey, entryValue);
                    }
                }
            }

        } else if (jsonObj instanceof JSONArray) {
            // 如果是数组JSONArray
            JSONArray parseJsonObj = (JSONArray) jsonObj;
            if (parseJsonObj.isEmpty()) {
                // 如果是数组，返回空集
                flatMap.put(key, parseJsonObj);
            } else {
                for (int i = 0; i < parseJsonObj.size(); i++) {
                    reduce(flatMap, key + "[" + i + "]", parseJsonObj.get(i));
                }
            }
        }else {
            flatMap.put(key, jsonObj);
        }
    }
}
